Release 10.1A: OpenEdge Development:
Progress 4GL Handbook
Looking at preprocessor values in the Code Preview
The first statement already looks pretty strange:
What’s that all about? A name enclosed in braces and preceded by an ampersand tells you this is a Progress preprocessor value. You are probably familiar with preprocessor values from other languages you’ve used. It is nothing more than a substitution string. It’s defined up near the beginning of the procedure file, and everywhere it occurs in the 4GL code, the Progress syntax analyzer replaces it with the string it’s been defined to represent. That way, you (or the AppBuilder) can define a commonly used string of code once and use it multiple times in your procedure.
The AppBuilder generates the definition of this preprocessor value. Normally you don’t need to look at it, so it’s in a special section that isn’t displayed along with the rest of your code sections.
![]()
To look at the preprocessor definition:
- Return to the AppBuilder main window and press F5 or select Compile
Code Preview from the menu. The Code Preview dialog box appears and shows all the code for the whole procedure.
- Scroll down in this dialog box to the section marked Preprocessor Definitions to find the definition of
OPEN-QUERY-CustQuery, as shown in Figure 4–4.Figure 4–4: Preprocessor definition in the Code Preview window
![]()
&Scoped-definemeans that this definition is scoped to just this procedure file, rather than being available to any other source files that are associated with this one. From this line you see that the preprocessorOPEN-QUERY-CustQueryis defined to represent the textOPEN QUERY CustQuery FOR EACH Customer SHARE-LOCK. In later chapters you’ll explore the differences between defining and opening a query on a table and just retrieving the data using aFOR EACHstatement by itself. For now it’s enough to understand that the query namedCustQuerydefines the set of data to be retrieved, theOPEN QUERYstatement starts the retrieval, and then other statements that you’ll see next actually walk through the data row by row. The query definition itself is in another part of the AppBuilder-generated code, and just saysDEFINE QUERY CustQuery FOR Customer.Positioning within the query
The first statement opens that Customer query and sets you up to retrieve and display each of the Customer records in turn. Now look at the next statement:
This statement retrieves the first Customer record using the query
CustQuery.Moving on, you see a
DISPLAYstatement, which should be familiar to you. It has anIF-THENconstruct in front of it that you haven’t seen before, but like most Progress 4GL statements, it’s self-explanatory. If the query turns out to be empty, or if you’ve reached the end of it, then you don’t want to try to display anything. The phraseIF AVAILABLE Customerchecks for that:
Because a field name might occur in more than one table used in the procedure, the AppBuilder puts the table name in front of each field name, as in
Customer.CustNum. This is a good practice for you to follow in the code you write unless your field names are all guaranteed to be unique.The end of the
DISPLAYstatement has a qualifier you didn’t see in previous chapters either,WITH FRAME CustQuery. But you can certainly tell what it does. Chapter 2, "Using Basic 4GL Constructs," explains that Progress uses frames to define different display areas, and that each field and block of code is associated with a frame. If you don’t name the frames yourself, you get default frames. If you need to, you can give each frame a name and specify that frame in aDISPLAYstatement. Then Progress knows exactly where each displayed field or other object should go. You renamed your window’s default frameCustQueryearlier, and here you see that name being used. And remember the AppBuilder uses the same name for the frame’s default query.The second qualifier is understandable, too. If your procedure happened to define more than one window, then you would have to tell it which frames go in which window. Here the code makes that explicit, by appending the phrase
IN WINDOW CustWin.So apart from these qualifiers this statement should look familiar. Now look at the next statement:
Not surprisingly, this statement enables each of the fields for data entry, so that you could make changes to a record and then save it. Also it enables the browse control itself so that you can scroll it up and down. At this time, you won’t actually add a Save button to this window to let you save changes (you’ll do that in Chapter 16 "Updating Your Database and Writing Triggers").
Next is another preprocessor value:
If you do a Code Preview again (or refer to Figure 4–4) you can see that this value represents the statement
OPEN QUERY OrderBrowse FOR EACH Order OF Customer NO-LOCK INDEXED-REPOSITION. You’ll get to details likeNO-LOCKversusSHARE-LOCKand whatINDEXED-REPOSITIONmeans in Chapter 12, " Using the Browse Object." Otherwise, you should recognize this as the query you built in the Query Builder when you dropped the browse control onto the window.The final executable statement is:
This statement tells Progress at run time to make the window visible.
And finally, as you learned in the Chapter 3, "Running Progress 4GL Procedures," every internal procedure must end with an
END PROCEDUREstatement:
This is all the code that’s needed to make all the things happen that you saw when you ran the window. It opens two different queries representing a parent-child relationship between Customers and Orders. It displays and then enables the Customer fields and the Order browse. And it views the window itself. All this happens in about ten lines of 4GL code. And you didn’t have to write any of it yourself.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |